
#include "heaviside_tiling.h"
#include "register/op_def_registry.h"
#include "tiling/platform/platform_ascendc.h"
#define BLOCK_SIZE 32
#define BUFFER_NUM 1
#define INOUTNUM 3
namespace optiling {
static ge::graphStatus TilingFunc(gert::TilingContext* context)
{
  HeavisideTilingData tiling;
  uint64_t ub_size;
  auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
  ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ub_size);
  int16_t aivNum = 1;

  uint64_t typeSize = GetSizeByDataType(context->GetInputDesc(0)->GetDataType());
  int32_t blockElem = BLOCK_SIZE / typeSize;
  int32_t totalLength = context->GetInputTensor(0)->GetShapeSize();
  int32_t totalLengthAligned = (totalLength+blockElem-1) / blockElem * blockElem;

  uint32_t totalBlocks = totalLengthAligned / blockElem;
  uint32_t coreDataNum;

  coreDataNum = totalBlocks / aivNum;
  uint32_t tail = totalBlocks %aivNum;
  uint32_t iter = ub_size/INOUTNUM/BUFFER_NUM/BLOCK_SIZE;

  tiling.set_iter(iter);
  tiling.set_coreDataNum(coreDataNum);
  tiling.set_tail(tail);
  context->SetBlockDim(aivNum);
  tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
  context->GetRawTilingData()->SetDataSize(tiling.GetDataSize());

  return ge::GRAPH_SUCCESS;
}
}


namespace ge {
static ge::graphStatus InferShape(gert::InferShapeContext* context)
{
    const gert::Shape* x1_shape = context->GetInputShape(0);
    gert::Shape* y_shape = context->GetOutputShape(0);
    *y_shape = *x1_shape;
    return GRAPH_SUCCESS;
}
}


namespace ops {
class Heaviside : public OpDef {
public:
    explicit Heaviside(const char* name) : OpDef(name)
    {
        this->Input("input")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});
        this->Input("values")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});
        this->Output("out")
            .ParamType(REQUIRED)
            .DataType({ge::DT_FLOAT, ge::DT_FLOAT16})
            .Format({ge::FORMAT_ND, ge::FORMAT_ND})
            .UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND});

        this->SetInferShape(ge::InferShape);

        this->AICore()
            .SetTiling(optiling::TilingFunc);
        this->AICore().AddConfig("ascend910b");

    }
};

OP_ADD(Heaviside);
}
